// Bachelor of Software Engineering 
// Media Design School 
// Auckland
// New Zealand
// 
// (c) 2005 - 2014 Media Design School 
// 
// File Name : Game.h
// Description : Game header
// Author : Serge Radinovich
// Mail : srad015@hotmail.com

#pragma once
#include <Windows.h>
#include "Win32GameEngine.h"
#include "CardPileGroup.h"
#include "Stock.h"
#include "Tableau.h"
#include "Foundation.h"
#include "Move.h"

#include "resource.h"

#include <algorithm>
#include <stack>
#include <typeinfo.h>


//Core game class
//Does not have an update() function because all actions are event-based
class Game : public Win32GameEngine
{
	
	std::stack<Move*> m_Moves;					//Stack of moves made during game to undo moves
	std::stack<int> m_PointsGained;				//Stack of points gained to undo points
		
	std::vector<Card*> m_Cards;					//Initial cards used to populate the game board
	
	Vector2 m_CardMouseDist;					//Vector between mouse click and card clicked

	
	std::list<Card*> m_CardsGrabbed;				//List of cards that player is currently dragging
	std::list<Card*> m_CardsMoved;					//List of cards moved for undoing moves
	std::list<Card*>* m_pListCardsGrabbedFrom;		//Pointer to list last cards were grabbed from
	std::list<Card*>* m_pListDepositedTo;			//Pointer to list last cards were deposited to
	CardPileGroup* m_pPileGroupTakenFrom;			//Pointer to pile group cards taken from


	//CardPiles
	Foundation* m_pFoundation;
	Tableau* m_pTableau;
	Stock* m_pStock;

	//Singleton
	static Game* pGame;
	HBRUSH hbrush;

	//Score keeping / time
	int Score;
	int MovesTaken;
	int LastTime;
	int TimeInSeconds;
	bool m_bInitializing;
	bool m_bGameOver;

	CardPileGroup* IsolateCardPileGroup(Vector2 _mouseClick);
	bool CheckGameWon();
	
	//Undo Button
	GameObject m_UndoButton;
	bool m_bButtonPushed;
	void ProcessUndoButton();
	void ActivateUndoButton();

	int iDisplayLength;

	void CheckLength(int _i, int _addLength);

public:

	static Game* CreateGame(HWND _hWnd, HINSTANCE _hIstance,HDC hDC);

	Game(HWND _hWnd, HINSTANCE _hInstance, HDC _hDC);
	~Game();

	static Game* GetGameInstance();
	HINSTANCE GetAppInstance();
	HWND GetWindow();
	BackBuffer* GetBackBuffer();

	void Draw();

	void MouseClick(Vector2 _clickPos);
	void MouseRelease(Vector2 _clickPos);
	void MoveGrabbedCards(Vector2 _mousePos);

	void UndoMove();
	bool GameOver();
	void GetScoreTimeAndMoves(int& _iScore, int& _iTime, int& _iMoves);

	void ExecuteOneFrame();

	void Reinitialize();

	void DrawNullSpaces();

};
